﻿#include<iostream>
#include<algorithm>
using namespace std;

////c语言的风格
// typedef  struct Str1
//{
//	int a;
//	//...
//}Str1;
//
//
////c++的风格
// struct Str2
// {
//	 int a;
//	 //定义函数
//	 int Add(int x, int y)
//	 {
//		 return x + y;
//	 }
//	 //...
// };


// class test1 //class - 关键字  test1 -- 命名
// {
//	 //公有
// public:
//	 //类内声明
//	 int Add(int x, int y);
// };
//
// //类外实现
// int test1::Add(int x, int y)
// {
//	 return x + y;
// }
//
//int main()
//{
//	//类    A为实例化的对象
//	test1 A;
//
//	return 0;
//}

 //class test1 //class - 关键字  test1 -- 命名
 //{
 //public:
 //int a;
 //};


//实例化
 //int main()
 //{
	// //类    A为实例化的对象
	// test1 A;
	// //通过 . 引用
	// A.a = 10;
	// cout << A.a << endl;
	// return 0;
 //}

 //class test1 //class - 关键字  test1 -- 命名
 //{
 //public:
	// char a;
	// int b;
 //};


 ////空类的大小
 // 

 //class test2
 //{
 //public:
 //};
 //int main()
 //{
	// //空类的大小
	// cout << sizeof(test2) << endl; 
	// return 0;
 //}


//this指针

 //日期类
 //class Date
 //{
 //public:
	// //void Init(  Date * const this    int year, int month, int day)
	// void Init(int year, int month, int day)
	// {
	//	 //this->_year 
	//	 _year = year;
	//	 //this->_month;
	//	 _month = month;
	//	// this->_day;
	//	 _day = day;
	// }

	// void Print()
	// {
	//	 cout << _year << '-' << _month << "-" << _day << endl;
	// }

 //private:
	// int _year; //年
	// int _month; //月
	// int _day; //日

 //};

 //int main()
 //{
	// Date D1;
	// Date D2;
	// 
	// // D1.Init( &D1,1, 1, 1);
	// D1.Init(1, 1, 1);

	// // D2.Init( &D2,2, 2, 2);
	// D2.Init(2, 2, 2);

	// return 0;
 //}


//// 1.下面程序编译运行结果是？ A、编译报错 B、运行崩溃 C、正常运行
//class A
//{
//public:
//	void Print()
//	{
//		cout << "Print()" << endl;
//	}
//private:
//	int _a;
//};
//int main()
//{
//	A* p = nullptr;
//	p->PrintA();
//	return 0;
//}


//// 1.下面程序编译运行结果是？ A、编译报错 B、运行崩溃 C、正常运行
//class A
//{
//public:
//	void PrintA()
//	{
//		cout << _a << endl;
//	}
//private:
//	int _a;
//};
//int main()
//{
//	A* p = nullptr;
//	p->PrintA();
//	return 0;
//}


 //六大默认成员函数

 //构造函数
 //class test01
 //{
 //public:
	// //构造函数  - 无参构造函数   无返回值，与类名相同
	// test01()
	// {
	//	 cout << "test01()" << endl;
	// }

	// //构造函数的重载 - 有参构造   可以重载
	// test01(int a)
	// {
	//	 cout << "test01(int a)" << endl;
	// }

 //private:
	// int _a;
	//
 //};
 //

 //int main()
 //{
	// //如函数 void Add()    void - 类型  Add - 函数名  () - 参数列表
	// //test01 p1();	 test01  -类型 p1 - 函数名  () - 参数列表    错误使用
	// //test01 p1;		//正确使用

	// test01 p2(10);	//自动调用有参构造

	// return  0;
 //}

 //// 构造函数
 //class test02
 //{
 //public:
	// //构造函数  - 无参构造函数   无返回值，与类名相同
	// test02()
	// {
	//	 cout << "test02()" << endl;
	// }

	// //构造函数的重载 - 有参构造   可以重载
	// test02(int a = 10)
	// {
	//	 cout << "test02(int a)" << endl;
	// }

 //private:
	// int _a;

 //};


 //int main()
 //{
	// test02 p1;

	// return  0;
 //}
//
// 
// 
// 对自定义类型
//typedef struct N
//{
//	N() { cout << "struct N" << endl; }
//	int i;
//}N;
//
//union E
//{
//	E() { cout << "union E" << endl; }
//	int i;
//};
//
// class test02
// {
// public:
//	 test02()
//	 {
//		 cout << "test02()" << endl;
//	 }
// private:
//	 int _a;
//
// };
//
//// 构造函数
//class test03
//{
//public:
//	
//	int _a;
//	test02 p;
//	N n;
//	E e;
//};
//
////初始化栈
//class Stack
//{
//public:
//	Stack(int capacity = 4) //利用全缺省参数
//	{
//		_capacity = capacity;
//		_top = 0;
//
//		//申请空间
//		_a = new int[_capacity];
//	}
//
//private:
//	//数组指针
//	int* _a;
//	//容量
//	int _capacity;
//	//栈顶后一个位置
//	int _top;
//};

////构造函数的默认值
//class test02
//{
//public:
//	test02()	//不进行显示进行初始
//	{
//		//...
//	};
//	test02(int a,int b)
//		:_a(a)
//		,_b(b)
//	{
//		//...
//	}
//	void Print()
//	{
//		cout << _a << endl << _b << endl;
//	}
//
//private:
//	int _a = 10;
//	int _b = 10;
//
//};
//
//int main()
//{
//	test02 a;	//使用无参构造
//	test02 b(20, 20);	//有参构造
//
//	a.Print();
//	b.Print();
//
//	return 0;
//}

////初始化列表
//class A
//{
//public:
//	A(int a)
//	{
//
//	};
//};
//
//class test03
//{
//public:
//
//	//初始化顺序按声明顺序初始化
//	test03(A a, int b,int c) :_c(c),_a(a),_b(b) 
//	{
//		//,,,
//	}
//
//
//private:
//	//自定义类型
//	A _a;
//	//const成员
//	const int _b;
//	//引用
//	int& _c;
//};






//析构函数




//class test04
//{
//public:
//	test04()
//	{
//		cout << "test04()" << endl;
//	}
//
//	~test04()
//	{
//		cout << "~test04()" << endl;
//	}
//};
//
//class test05
//{
//public:
//	test05()
//	{
//		cout << "test05()" << endl;
//	}
//	~test05()
//	{
//		cout << "~test05()" << endl;
//	}
//	
//private:
//	//内置类型
//	int _a;
//	//自定义类型
//	test04 p;
//};
//
//
//class Stack
//{
//public:
//	//构造函数
//	Stack(int capacity = 4) //利用全缺省参数
//	{
//		_capacity = capacity;
//		_top = 0;
//
//		//申请空间
//		_a = new int[_capacity];
//	}
//
//	//析构函数
//	~Stack()
//	{
//		//释放申请的空间
//		free(_a);
//		_a = nullptr;
//
//		_top = _capacity = 0;
//	}
//
//private:
//	//数组指针
//	int* _a;
//	//容量
//	int _capacity;
//	//栈顶后一个位置
//	int _top;
//};



//class A
//{
//public:
//	~A()
//	{
//		cout << "~A()" << endl;
//	}
//};
//
//class B 
//{
//public:
//	//自定义类型
//	A p;
//	//内置类型
//	int a;
//};
//
//int main()
//{
//	B p;
//	return  0;
//}



//拷贝构造

//class test06
//{
//public:
//	test06(int a,int b):_a(a),_b(b)
//	{}
//
//	//拷贝构造
//	test06(test06 &a)
//	{
//		_a = a._a;
//		_b = a._b;
//	}
//
//	void Print()
//	{
//		cout << _a << " " << _b<<endl;
//	}
//
//private:
//	int _a ;
//	int _b ;
//};
//
//
//
//int main()
//{
//	test06 a(20,20);
//	test06 b(a);
//
//	a.Print();
//	b.Print();
//
//	return 0;
//}


//class A
//{
//public:
//	A(int a) :_a(a)
//	{
//
//	}
//
//	//拷贝构造
//	A(A& a)
//	{
//		cout << "A(A& a)" << endl;
//	}
//
//	int _a;
//
//};
//
//class test06
//{
//public:
//	test06(A a, int b) :_a(a), _b(b)
//	{
//	}
//private:
//	//自定义类型
//	A _a;
//	//内置类型
//	int _b;
//};
//
//int main()
//{
//	A a(10);
//
//	test06 b(a, 20);
//	test06 c(b);
//
//	return 0;
//}

////深拷贝和浅拷贝
//class test07
//{
//public:
//	test07(int* a):_a(a)
//	{
//	}
//	~test07()
//	{
//		delete[]_a;
//	}
//	test07(test07& p)
//	{
//		//重新开辟空间
//		int* _a = new int[10];
//
//		//拷贝
//		memcpy(_a, p._a, sizeof(int)*10);
//		
//	}
//private:
//	int* _a;
//};
//
//int main()
//{
//	int* a = new int[10];
//	for (int i = 0; i < 10; i++)
//	{
//		a[i] = i;
//	}
//	test07 p(a);
//	return 0;
//}
// 

//赋值运算符和拷贝构造的区别
//{
//	A a;
//	//只有a已经存在 使用拷贝构造
//	A b = a;
//
//	A c;
//	A d;
//	//c\d都是已经存在的了， 使用赋值运算符重载
//	c = d;
//
//}

////const成员 
//class test08
//{
//public:
//	test08(int a) :_a(a)
//	{
//
//	}
//	void Print()const
//	{
//		cout << _a;
//	}
//	int get() 
//	{
//		Print();
//		return _a;
//	}
//private:
//	int _a;
//
//};


////取地址符重载
//class test08
//{
//public:
//	//取地址
//	test08* operator&()
//	{
//		return this;
//	}
//	// const取地址
//	const test08* operator&()const
//	{
//		return this;
//	}
//
//int main()
//{
//	 test08 p(10);
//	p.Print();
//
//	return  0;
//}


// explicit关键字

//隐式类型转换


//int main()
//{
//	double d = 1.2;
//	//再用 d 给 i 进行赋值时，会进行隐式类型转换。
//	//过程：产生 tmp  = 1 ,再用 tmp 给 i 进行赋值
//	int i = d;
//
//	return 0;
//}

//单参数隐式类型转换
//class A
//{
//public:
//	//有参构造  单参数
//	A(int a)
//		:_a(a)
//	{
//		cout << "A(int a)" << endl;
//	}
//
//	//拷贝构造
//	A(const A & a)
//	{
//		cout << "A(const A & a)" << endl;
//	}
//private:
//	int _a;
//
//};
//
//int main()
//{
//	A aa = 3;
//	//等价与  A aaa(3) , A aa = aaa; 
//	//先将 3（int） 隐式转换为 自定义类型 A （tmp），再aa = tmp （拷贝构造）
//
//	return 0;
//}

//多参数隐式类型转换
//class A
//{
//public:
//	//有参构造  多参数 + explicit
//	/*explicit A(int a,int b)
//		:_a(a)
//		,_b(b)
//	{
//		cout << "A(int a)" << endl;
//	}*/
//
//	 A(int a, int b)
//		:_a(a)
//		, _b(b)
//	{
//		cout << "A(int a)" << endl;
//	}
//private:
//	int _a;
//	int _b;
//};
//
//int main()
//{
//	//调用格式 ，也可 aa{1,2},但是不建议这种
//	A aa = { 1,2 };
//	return 0;
//}


//int main()
//{
//	double d = 1.12;
//
//	//int i = d; 正常进行隐式转换
//
//	//int& i = d;	//引用临时变量  过程 const int tmp -> int &i = tmp 但是tmp是常量所以会报错 
//
//	//正确做法	//临时变量如果被引用生命周期会延长，不然用完就销毁了
//	const int& i = d;
//	return 0;
//}


//static 成员

//class A
//{
//public:
//	//静态成员函数
//	static void Print()
//	{
//		Add();
//		cout << _a << endl;
//		//静态函数不能访问非静态成员
//		//cout << _b << endl;
//	}
//
//	void Add()
//	{
//		Print();
//	}
//	//静态成员变量  声明
//	static int _a;
//	int _b = 10;
//};
//
////在类外定义
//int A::_a = 10;
//
//int main()
//{
//	A a1;
//	cout << sizeof(a1) << endl; // 大小为 4 ，_a 存在静态区
//
//	A a2;
//	cout << "直接通过类来访问" << A::_a << endl;
//	cout << "a1:" << a1._a << endl;		// a1._a == a2._a 这个成员变量共享
//	cout << "a2:" << a2._a << endl;		//当前在公共区域，当设置为私有时对象就不可访问了
//
//	return 0;
//}

////友元函数
//class A
//{
//	//声明友元函数
//	friend ostream& operator<<(ostream& _cout, A& a);
//public:
//
//
//private:
//	int _a = 10;
//};
//
//ostream& operator<<(ostream& _cout, A &a)
//{
//	//作为友元函数来访问私有成员
//	_cout << a._a << endl;
//	return _cout;
//}
//
//int main()
//{
//	return 0;
//}


////友元类
//class B;
//class A
//{
//	//B 类作为 A类的友元
//	friend class B;
//public:
//	void Print(B& b)
//	{
//		//A类不可以访问B类 ，不具有交换性
//		//cout << b._b << endl;
//	}
//	
//
//private:
//	int _a = 10;
//};
//
//class B
//{
//	friend class C;
//public:
//	void Print(A& a)
//	{
//		//可以访问非公有成员
//		cout << a._a << endl;
//	}
//private:
//	int _b = 10;
//};
//
//class C
//{
//public:
//	void Print(A& a)
//	{
//		//友元关系不能传递，这里无法访问到A类的非公有成员
//		//cout << a._a << endl;
//	}
//};
//
//
//
//
//int main()
//{
//	
//	B b;
//	A a;
//	b.Print(a);
//	return 0;
//}


////内部类
//class A
//{
//public:
//	//B类 默认作为 A类友元
//	class B
//	{
//	public:
//		void P(A& a)
//		{
//			//可以直接访问a的非公有成员
//			cout << a._a << endl;
//
//			//可以直接访问A类的静态成员
//			cout << s_a << endl;
//		 }
//
//	private:
//		int _b = 10;
//
//	};
//
//
//
//private:
//	int _a = 10;
//	static int s_a;
//};
//int A::s_a = 20;
//
//
//int main()
//{
//	A a;
//
//	cout << "A类的大小:" << sizeof(a) << endl; //4,不受到B类的干扰
//
//	//使用B类
//	A::B  b;
//
//	//访问b类成员函数
//	b.P(a);
//
//	return 0;
//}

////匿名对象
//class A
//{
//public:
//	A(int a = 10)
//		:_a(a) 
//	{}
//	int get()
//	{
//		return _a;
//	}
//
//private:
//	int _a;
//
//};
//
//int main()
//{
//	//正常实例化对象  生命周期从定义到main函数结束
//	A a1;
//	A a2(10);
//
//	//匿名对象	生命周期仅仅就是定义这行
//	A();
//	A(10);
//
//	//一些作用如：想调用非静态成员函数
//
//	//用匿名对象
//	A().get();	
//
//	//一般用法  ,比匿名对象繁琐
//	A a3;
//	a3.get();
//
//	return 0;
//
//}

//编译器对拷贝构造的一些优化
class A
{
public:
	A(int a = 10):_a(a)
	{
		cout << "A() " << endl;
	}
	A(const A& a)
	{
		cout << "A(const A& a)" << endl;
	}
private:
	int _a ;
};

A fu1(A a)
{
	A aa;
	return aa;
}

int main()
{
	//构造 + 拷贝 -> 拷贝

	//正常实例化对象传值
	A a1;
	//fu1(a1);

	////匿名对象
	//fu1(A());

	////隐式转换
	//A a2 = 10;

	//拷贝 + 拷贝 -> 拷贝
	A a3 = fu1(a1);

	//无法优化的情况
	A a4;
	a4 = fu1(a1);	//属于赋值了



	return 0;
}

